#include "cardpool.h"

#include <QDebug>
#include <QTime>

CardPool::CardPool(QString filename) :
    QObject(0)
{
    model = new QStandardItemModel(0, 1);
    if (filename != NULL)
        loadFromFile(filename);
    m_ViewObject = ICardViewObjectData::getViewObject(this, ICardViewObjectData::CARD_POOL);
}

AbstractCard * CardPool::AddCard (AbstractCard * newCard)
{
    if ( newCard == NULL)
        return newCard;

    m_CardPool << newCard;

    model->insertRow(model->rowCount());

    model->setData(model->index(model->rowCount() - 1, 0), newCard->property("CardName").toString().append(": ").append(newCard->property("CardType").toString()));
    model->setData(model->index(model->rowCount() - 1, 0), newCard->toXmlDefinition(), Qt::UserRole);

#ifdef TRACE_ON
    qDebug() << newCard->property("CardName").toString() << " added";
#endif
    return newCard;
}

void CardPool::RemoveCard(int index)
{
    model->removeRow(index);
    m_CardPool.remove(index);
}

void CardPool::changeCard(const QModelIndex & index, const QVariant & value, int role)
{
    model->setData(index, value, role);
    QDomDocument *doc = new QDomDocument();
    doc->setContent(value.toString());
//    AbstractCard * card = m_CardPool.at(index.row());
//    card = new AbstractCard(doc);
    m_CardPool[index.row()] = new AbstractCard(doc);
}

void CardPool::RemoveCard(AbstractCard * card)
{
    RemoveCard(m_CardPool.indexOf(card));
}

AbstractCard *CardPool::getRandomCard(bool vRemoveCard)
{
    QTime midnight(0, 0, 0);
    qsrand(midnight.secsTo(QTime::currentTime()));

    int cardIndex = qrand() % m_CardPool.count() - 1;
    AbstractCard * result;
    if (vRemoveCard)
    {
        result = new AbstractCard(m_CardPool.at(cardIndex)->toXmlDefinition());
        m_CardPool.remove(cardIndex);
    }
    else
        result = m_CardPool.at(cardIndex);
    return result;
}

int CardPool::getCount()
{
    return m_CardPool.count();
}

QString CardPool::toXmlDefinition()
{
    QDomDocument *doc = new QDomDocument();
    QDomElement root = doc->createElement("CardPool");


    QDomDocument *docCard = new QDomDocument();
    foreach (AbstractCard *card, m_CardPool)
    {
        docCard->setContent(card->toXmlDefinition());
        root.appendChild(docCard->documentElement());
    }
    doc->appendChild(root);
    return doc->toString(4);
}

void CardPool::fromXmlDefinition(QDomDocument * doc)
{
    QDomElement rootElement = doc->documentElement();
    QDomNodeList elements = rootElement.elementsByTagName(WORD_CARD);
    for ( int i = 0; i < elements.count(); ++ i)
    {
        AddCard(CardPool::CreateCard(elements.item(i)));
    }

#ifdef TRACE_ON
    AbstractCard * card = m_CardPool.at(0);
    for (int i = 1; i < card->metaObject()->propertyCount(); ++i)
    {
        qDebug() <<  card->metaObject()->property(i).name() << " = " << ((CreatureCard*) card)->property(card->metaObject()->property(i).name());
    }
#endif
}

void CardPool::fromXmlDefinition(QString xmlDefinition)
{
    QDomDocument *doc = new QDomDocument();
    doc->setContent(xmlDefinition);
    fromXmlDefinition(doc);
}

void CardPool::loadFromFile(QString fileName)
{
    QFile file(fileName);
    QString text;
    if (file.open(QIODevice::ReadOnly))
    {
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line = in.readLine();
            text.append(line);
        }
        file.close();
    }

    QDomDocument *doc;
    doc = new QDomDocument("Card Pool");
    doc->setContent(text);
    fromXmlDefinition(doc);
    qDebug () << "exported successfully";
}

AbstractCard *CardPool::CreateCard(QDomNode elementCard)
{
    QDomDocument doc(WORD_CARD);
    QDomNode node = doc.appendChild(elementCard.cloneNode());

    QDomNodeList nodes = node.toElement().elementsByTagName(WORD_TYPE);
    if (nodes.isEmpty())
        return NULL;

    QDomElement cardType = nodes.item(0).toElement();
    QString value = cardType.attribute(WORD_ATTR_VALUE, NULL);

    if (value == WORD_TYPE_CREATURE)
        return new CreatureCard(&doc);
    else if (value == WORD_TYPE_LAND)
        return new LandCard(&doc);
    else if (value != NULL)
        return new AbilityCard(&doc);
    else
        return NULL;
}
